This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

library(velocyto.R)
载入需要的程辑包:Matrix
library(SeuratWrappers)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
library(Seurat)

载入程辑包:‘Seurat’

The following objects are masked from ‘package:SeuratWrappers’:

    ALRAChooseKPlot, ExportToCellbrowser, ReadAlevin, RunALRA, StopCellbrowser
source("tianfengRwrappers.R")
载入需要的程辑包:dplyr

载入程辑包:‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union

载入需要的程辑包:reticulate
载入需要的程辑包:tidyr

载入程辑包:‘tidyr’

The following objects are masked from ‘package:Matrix’:

    expand, pack, unpack


载入程辑包:‘MySeuratWrappers’

The following objects are masked from ‘package:Seurat’:

    DimPlot, DoHeatmap, LabelClusters, RidgePlot, VlnPlot


载入程辑包:‘cowplot’

The following object is masked from ‘package:ggpubr’:

    get_legend

载入需要的程辑包:viridisLite

载入程辑包:‘reshape2’

The following object is masked from ‘package:tidyr’:

    smiths

NOTE: Either Arial Narrow or Roboto Condensed fonts are required to use these themes.
      Please use hrbrthemes::import_roboto_condensed() to install Roboto Condensed and
      if Arial Narrow is not on your system, please see https://bit.ly/arialnarrow

Registered S3 method overwritten by 'enrichplot':
  method               from
  fortify.enrichResult DOSE
clusterProfiler v3.14.3  For help: https://guangchuangyu.github.io/software/clusterProfiler

If you use clusterProfiler in published research, please cite:
Guangchuang Yu, Li-Gen Wang, Yanyan Han, Qing-Yu He. clusterProfiler: an R package for comparing biological themes among gene clusters. OMICS: A Journal of Integrative Biology. 2012, 16(5):284-287.
Registering fonts with R

载入程辑包:‘plotly’

The following object is masked from ‘package:ggplot2’:

    last_plot

The following object is masked from ‘package:stats’:

    filter

The following object is masked from ‘package:graphics’:

    layout

载入需要的程辑包:Biobase
载入需要的程辑包:BiocGenerics
载入需要的程辑包:parallel

载入程辑包:‘BiocGenerics’

The following objects are masked from ‘package:parallel’:

    clusterApply, clusterApplyLB, clusterCall, clusterEvalQ, clusterExport, clusterMap, parApply,
    parCapply, parLapply, parLapplyLB, parRapply, parSapply, parSapplyLB

The following objects are masked from ‘package:dplyr’:

    combine, intersect, setdiff, union

The following object is masked from ‘package:Matrix’:

    which

The following objects are masked from ‘package:stats’:

    IQR, mad, sd, var, xtabs

The following objects are masked from ‘package:base’:

    anyDuplicated, append, as.data.frame, basename, cbind, colnames, dirname, do.call, duplicated,
    eval, evalq, Filter, Find, get, grep, grepl, intersect, is.unsorted, lapply, Map, mapply, match,
    mget, order, paste, pmax, pmax.int, pmin, pmin.int, Position, rank, rbind, Reduce, rownames,
    sapply, setdiff, sort, table, tapply, union, unique, unsplit, which, which.max, which.min

Welcome to Bioconductor

    Vignettes contain introductory material; view with 'browseVignettes()'. To cite Bioconductor, see
    'citation("Biobase")', and for packages 'citation("pkgname")'.

载入需要的程辑包:e1071

载入程辑包:‘widgetTools’

The following object is masked from ‘package:dplyr’:

    funs


载入程辑包:‘DynDoc’

The following object is masked from ‘package:BiocGenerics’:

    path


载入程辑包:‘DT’

The following object is masked from ‘package:Seurat’:

    JS
# dataset1
velodata1 <- ReadVelocity(file ="./velo_data/RPE004.loom")
reading loom file via hdf5r...
velodata2 <- ReadVelocity(file ="./velo_data/RPE005.loom")
reading loom file via hdf5r...
velodata3 <- ReadVelocity(file ="./velo_data/RPE006.loom")
reading loom file via hdf5r...
#匹配两次的barcode
func <- function(s)
{
  s <- strsplit(s,".*:",fixed = F)[[1]][2]
  s <- strsplit(s,"x",fixed = T)[[1]]
  s <- paste0("CA_sample1.txt_",s)#s为barcode
  return(s)
}

velodata1[["spliced"]]@Dimnames[[2]] = as.character(lapply(velodata1[["spliced"]]@Dimnames[[2]],func))
velodata1[["unspliced"]]@Dimnames[[2]] = as.character(lapply(velodata1[["unspliced"]]@Dimnames[[2]],func))
velodata1[["ambiguous"]]@Dimnames[[2]] = as.character(lapply(velodata1[["ambiguous"]]@Dimnames[[2]],func))


func <- function(s)
{
  s <- strsplit(s,".*:",fixed = F)[[1]][2]
  s <- strsplit(s,"x",fixed = T)[[1]]
  s <- paste0("CA_sample2.txt_",s)
  return(s)
}

velodata2[["spliced"]]@Dimnames[[2]] = as.character(lapply(velodata2[["spliced"]]@Dimnames[[2]],func))
velodata2[["unspliced"]]@Dimnames[[2]] = as.character(lapply(velodata2[["unspliced"]]@Dimnames[[2]],func))
velodata2[["ambiguous"]]@Dimnames[[2]] = as.character(lapply(velodata2[["ambiguous"]]@Dimnames[[2]],func))


func <- function(s)
{
  s <- strsplit(s,".*:",fixed = F)[[1]][2]
  s <- strsplit(s,"x",fixed = T)[[1]]
  s <- paste0("CA_sample3.txt_",s)
  return(s)
}

velodata3[["spliced"]]@Dimnames[[2]] = as.character(lapply(velodata3[["spliced"]]@Dimnames[[2]],func))
velodata3[["unspliced"]]@Dimnames[[2]] = as.character(lapply(velodata3[["unspliced"]]@Dimnames[[2]],func))
velodata3[["ambiguous"]]@Dimnames[[2]] = as.character(lapply(velodata3[["ambiguous"]]@Dimnames[[2]],func))
# CA_dataset1 <- readRDS("CA_dataset1.rds"
ds1 <- readRDS("ds1.rds")
sp1_velo <- as.Seurat(x = velodata1)

  |                                                                                                               
  |                                                                                                         |   0%Warning: Non-unique features (rownames) present in the input matrix, making unique

  |                                                                                                               
  |===================================                                                                      |  33%
  |                                                                                                               
  |======================================================================                                   |  67%
  |                                                                                                               
  |=========================================================================================================| 100%
sp2_velo <- as.Seurat(x = velodata2)

  |                                                                                                               
  |                                                                                                         |   0%Warning: Non-unique features (rownames) present in the input matrix, making unique

  |                                                                                                               
  |===================================                                                                      |  33%
  |                                                                                                               
  |======================================================================                                   |  67%
  |                                                                                                               
  |=========================================================================================================| 100%
sp3_velo <- as.Seurat(x = velodata3)

  |                                                                                                               
  |                                                                                                         |   0%Warning: Non-unique features (rownames) present in the input matrix, making unique

  |                                                                                                               
  |===================================                                                                      |  33%
  |                                                                                                               
  |======================================================================                                   |  67%
  |                                                                                                               
  |=========================================================================================================| 100%
merge_velo <- merge(sp1_velo, c(sp2_velo,sp3_velo))
merge_velo <- subset(merge_velo, cells = WhichCells(CA_dataset1))
Error in WhichCells(CA_dataset1) : 找不到对象'CA_dataset1'

saveRDS(merge_velo,"dataset1_velo.RDS")
merge_velo <- RunVelocity(object = merge_velo, deltaT = 1, kCells = 25, fit.quantile = 0.02, ncores = 3) # fitting gamma coefficients 用时长
Filtering genes in the spliced matrix
Filtering genes in the unspliced matrix
Calculating embedding distance matrix
calculating cell knn ... done
calculating convolved matrices ... done
fitting gamma coefficients ... done. succesfful fit for 4279 genes
filtered out 436 out of 4279 genes due to low nmat-emat correlation
filtered out 296 out of 3843 genes due to low nmat-emat slope
calculating RNA velocity shift ... done
calculating extrapolated cell state ... done
# saveRDS(merge_velo,"dataset2_AC_velo.RDS")
# merge_velo <- readRDS("dataset2_AC_velo.RDS")
ident.colors <- colors_list[1:length(x = levels(x = merge_velo))]
names(x = ident.colors) <- levels(x = merge_velo)
cell.colors <- ident.colors[Idents(object = merge_velo)]

names(x = cell.colors) <- colnames(x = merge_velo)
png("dataset1_velocity.png")
show.velocity.on.embedding.cor(emb = Embeddings(object = merge_velo, reduction = "umap"), vel = Tool(object = merge_velo, slot = "RunVelocity"), n = 200, scale = "sqrt", cell.colors = ac(x = cell.colors, alpha = 0.5), 
    cex = 0.8, arrow.scale = 3, show.grid.flow = TRUE, min.grid.cell.mass = 0.5, grid.n = 40, arrow.lwd = 1, 
    do.par = FALSE, cell.border.alpha = 0.1)
delta projections ... sqrt knn ... transition probs ... done
calculating arrows ... done
grid estimates ... grid.sd= 0.4975555  min.arrow.size= 0.009951109  max.grid.arrow.length= 0.04539128  done
dev.off()
null device 
          1 
# plot <- tSNE.velocity.plot(vel = Tool(object = sp1_velo, slot = "RunVelocity"))
source("../vascular-analysis/seuratToAnnDataCombined.R")
h5ad_output <- "dataset1_SMC_velo.h5ad"  

library(reticulate)
library(Matrix)
writeMM(t(merge_velo@assays$SCT@counts), file='combined.mtx')
NULL
writeMM(t(merge_velo@assays$spliced@counts), file='spliced.mtx')
NULL
writeMM(t(merge_velo@assays$unspliced@counts), file='unspliced.mtx')
NULL
write.csv(rownames(merge_velo@assays$spliced@counts), file = "genes.csv", row.names = FALSE)
write.csv(merge_velo@reductions$umap@cell.embeddings, file = "umap.csv", row.names = FALSE)
write.csv(merge_velo@reductions$pca@cell.embeddings, file = "pca.csv", row.names = FALSE)
write.csv(colnames(merge_velo@assays$spliced@counts), file = "cells.csv", row.names = FALSE)
write.csv(merge_velo@meta.data, file = "meta.csv", row.names = FALSE)

source_python('~/scRNAseq/vascular-analysis/build.py')
build(h5ad_output, pca = TRUE, umap = TRUE)
file.remove('combined.mtx')
[1] TRUE
file.remove('spliced.mtx')
[1] TRUE
file.remove('unspliced.mtx')
[1] TRUE
file.remove('genes.csv')
[1] TRUE
file.remove('cells.csv')
[1] TRUE
file.remove('umap.csv')
[1] TRUE
file.remove('pca.csv')
[1] TRUE
file.remove('meta.csv')
[1] TRUE

只在SMC亚群中进行

SMC_velo <- subset(merge_velo, idents = "SMC")
RunVelocity(object = SMC_velo, deltaT = 1, kCells = 25, fit.quantile = 0.02)
ident.colors <- colors_list[1:length(x = levels(x = SMC_velo))]
names(x = ident.colors) <- levels(x = SMC_velo)
cell.colors <- ident.colors[Idents(object = SMC_velo)]

names(x = cell.colors) <- colnames(x = SMC_velo)
png("SMC_velocity.png")
show.velocity.on.embedding.cor(emb = Embeddings(object = SMC_velo, reduction = "umap"), vel = Tool(object = SMC_velo, slot = "RunVelocity"), n = 200, scale = "sqrt", cell.colors = ac(x = cell.colors, alpha = 0.5), 
    cex = 0.8, arrow.scale = 3, show.grid.flow = TRUE, min.grid.cell.mass = 0.5, grid.n = 40, arrow.lwd = 1, 
    do.par = FALSE, cell.border.alpha = 0.1)
dev.off()

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ3RybCtTaGlmdCtFbnRlciouIAoKYGBge3J9CmxpYnJhcnkodmVsb2N5dG8uUikKbGlicmFyeShTZXVyYXRXcmFwcGVycykKbGlicmFyeShTZXVyYXQpCnNvdXJjZSgidGlhbmZlbmdSd3JhcHBlcnMuUiIpCgpgYGAKCmBgYHtyfQojIGRhdGFzZXQxCnZlbG9kYXRhMSA8LSBSZWFkVmVsb2NpdHkoZmlsZSA9Ii4vdmVsb19kYXRhL1JQRTAwNC5sb29tIikKdmVsb2RhdGEyIDwtIFJlYWRWZWxvY2l0eShmaWxlID0iLi92ZWxvX2RhdGEvUlBFMDA1Lmxvb20iKQp2ZWxvZGF0YTMgPC0gUmVhZFZlbG9jaXR5KGZpbGUgPSIuL3ZlbG9fZGF0YS9SUEUwMDYubG9vbSIpCmBgYAoKCmBgYHtyfQoj5Yy56YWN5Lik5qyh55qEYmFyY29kZQpmdW5jIDwtIGZ1bmN0aW9uKHMpCnsKICBzIDwtIHN0cnNwbGl0KHMsIi4qOiIsZml4ZWQgPSBGKVtbMV1dWzJdCiAgcyA8LSBzdHJzcGxpdChzLCJ4IixmaXhlZCA9IFQpW1sxXV0KICBzIDwtIHBhc3RlMCgiQ0Ffc2FtcGxlMS50eHRfIixzKSNz5Li6YmFyY29kZQogIHJldHVybihzKQp9Cgp2ZWxvZGF0YTFbWyJzcGxpY2VkIl1dQERpbW5hbWVzW1syXV0gPSBhcy5jaGFyYWN0ZXIobGFwcGx5KHZlbG9kYXRhMVtbInNwbGljZWQiXV1ARGltbmFtZXNbWzJdXSxmdW5jKSkKdmVsb2RhdGExW1sidW5zcGxpY2VkIl1dQERpbW5hbWVzW1syXV0gPSBhcy5jaGFyYWN0ZXIobGFwcGx5KHZlbG9kYXRhMVtbInVuc3BsaWNlZCJdXUBEaW1uYW1lc1tbMl1dLGZ1bmMpKQp2ZWxvZGF0YTFbWyJhbWJpZ3VvdXMiXV1ARGltbmFtZXNbWzJdXSA9IGFzLmNoYXJhY3RlcihsYXBwbHkodmVsb2RhdGExW1siYW1iaWd1b3VzIl1dQERpbW5hbWVzW1syXV0sZnVuYykpCgoKZnVuYyA8LSBmdW5jdGlvbihzKQp7CiAgcyA8LSBzdHJzcGxpdChzLCIuKjoiLGZpeGVkID0gRilbWzFdXVsyXQogIHMgPC0gc3Ryc3BsaXQocywieCIsZml4ZWQgPSBUKVtbMV1dCiAgcyA8LSBwYXN0ZTAoIkNBX3NhbXBsZTIudHh0XyIscykKICByZXR1cm4ocykKfQoKdmVsb2RhdGEyW1sic3BsaWNlZCJdXUBEaW1uYW1lc1tbMl1dID0gYXMuY2hhcmFjdGVyKGxhcHBseSh2ZWxvZGF0YTJbWyJzcGxpY2VkIl1dQERpbW5hbWVzW1syXV0sZnVuYykpCnZlbG9kYXRhMltbInVuc3BsaWNlZCJdXUBEaW1uYW1lc1tbMl1dID0gYXMuY2hhcmFjdGVyKGxhcHBseSh2ZWxvZGF0YTJbWyJ1bnNwbGljZWQiXV1ARGltbmFtZXNbWzJdXSxmdW5jKSkKdmVsb2RhdGEyW1siYW1iaWd1b3VzIl1dQERpbW5hbWVzW1syXV0gPSBhcy5jaGFyYWN0ZXIobGFwcGx5KHZlbG9kYXRhMltbImFtYmlndW91cyJdXUBEaW1uYW1lc1tbMl1dLGZ1bmMpKQoKCmZ1bmMgPC0gZnVuY3Rpb24ocykKewogIHMgPC0gc3Ryc3BsaXQocywiLio6IixmaXhlZCA9IEYpW1sxXV1bMl0KICBzIDwtIHN0cnNwbGl0KHMsIngiLGZpeGVkID0gVClbWzFdXQogIHMgPC0gcGFzdGUwKCJDQV9zYW1wbGUzLnR4dF8iLHMpCiAgcmV0dXJuKHMpCn0KCnZlbG9kYXRhM1tbInNwbGljZWQiXV1ARGltbmFtZXNbWzJdXSA9IGFzLmNoYXJhY3RlcihsYXBwbHkodmVsb2RhdGEzW1sic3BsaWNlZCJdXUBEaW1uYW1lc1tbMl1dLGZ1bmMpKQp2ZWxvZGF0YTNbWyJ1bnNwbGljZWQiXV1ARGltbmFtZXNbWzJdXSA9IGFzLmNoYXJhY3RlcihsYXBwbHkodmVsb2RhdGEzW1sidW5zcGxpY2VkIl1dQERpbW5hbWVzW1syXV0sZnVuYykpCnZlbG9kYXRhM1tbImFtYmlndW91cyJdXUBEaW1uYW1lc1tbMl1dID0gYXMuY2hhcmFjdGVyKGxhcHBseSh2ZWxvZGF0YTNbWyJhbWJpZ3VvdXMiXV1ARGltbmFtZXNbWzJdXSxmdW5jKSkKYGBgCgoKYGBge3J9CiMgQ0FfZGF0YXNldDEgPC0gcmVhZFJEUygiQ0FfZGF0YXNldDEucmRzIgpkczEgPC0gcmVhZFJEUygiZHMxLnJkcyIpCnNwMV92ZWxvIDwtIGFzLlNldXJhdCh4ID0gdmVsb2RhdGExKQpzcDJfdmVsbyA8LSBhcy5TZXVyYXQoeCA9IHZlbG9kYXRhMikKc3AzX3ZlbG8gPC0gYXMuU2V1cmF0KHggPSB2ZWxvZGF0YTMpCm1lcmdlX3ZlbG8gPC0gbWVyZ2Uoc3AxX3ZlbG8sIGMoc3AyX3ZlbG8sc3AzX3ZlbG8pKQptZXJnZV92ZWxvIDwtIHN1YnNldChtZXJnZV92ZWxvLCBjZWxscyA9IFdoaWNoQ2VsbHMoZHMxKSkKcm0oc3AxX3ZlbG8pCnJtKHNwMl92ZWxvKQpybShzcDNfdmVsbykKcm0odmVsb2RhdGExKQpybSh2ZWxvZGF0YTIpCnJtKHZlbG9kYXRhMykKYGBgCgoKYGBge3J9Cm1lcmdlX3ZlbG8gPC0gbWVyZ2VfdmVsbyAlPiUgCiAgICBQZXJjZW50YWdlRmVhdHVyZVNldChwYXR0ZXJuID0gIl5NVC0iLCBjb2wubmFtZSA9ICJwZXJjZW50Lm10IikgJT4lCiAgICBTQ1RyYW5zZm9ybSh2YXJzLnRvLnJlZ3Jlc3MgPSAicGVyY2VudC5tdCIsIHZlcmJvc2UgPSBGLGFzc2F5ID0gInNwbGljZWQiKSAlPiUgCiAgICBSdW5QQ0EoKSAlPiUgRmluZE5laWdoYm9ycyhkaW1zID0gMToyMCkgJT4lIAogICAgUnVuVU1BUChkaW1zID0gMToyMCkgJT4lIAogICAgRmluZENsdXN0ZXJzKHJlc29sdXRpb24gPSAwLjEpCgpWbG5QbG90KG1lcmdlX3ZlbG8sInBlcmNlbnQubXQiLGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKQpWbG5QbG90KG1lcmdlX3ZlbG8sIGZlYXR1cmVzID0gYygibkZlYXR1cmVfc3BsaWNlZCIsICJuQ291bnRfc3BsaWNlZCIpLCBuY29sID0gMixncm91cC5ieSA9ICJvcmlnLmlkZW50IikKCkRpbVBsb3QobWVyZ2VfdmVsbywgcmVkdWN0aW9uID0gInVtYXAiLHB0LnNpemUgPSAwLjUsbGFiZWwgPSBUKQoKbWVyZ2VfdmVsb0ByZWR1Y3Rpb25zW1sidW1hcCJdXSA8LSBkczFAcmVkdWN0aW9uc1tbInVtYXAiXV0KbWVyZ2VfdmVsb0ByZWR1Y3Rpb25zW1sidW1hcCJdXUBjZWxsLmVtYmVkZGluZ3MgPC1kczFAcmVkdWN0aW9uc1tbInVtYXAiXV1AY2VsbC5lbWJlZGRpbmdzW2NvbG5hbWVzKG1lcmdlX3ZlbG8pLF0KbWVyZ2VfdmVsbyRDbGFzc2lmaWNhdGlvbjEgPC0gSWRlbnRzKGRzMSkKSWRlbnRzKG1lcmdlX3ZlbG8pIDwtIG1lcmdlX3ZlbG8kQ2xhc3NpZmljYXRpb24xCkRpbVBsb3QobWVyZ2VfdmVsbywgcmVkdWN0aW9uID0gInVtYXAiLHB0LnNpemUgPSAwLjUsbGFiZWwgPSBUKQoKdW1hcHBsb3QoZHMxKQpmKCJMVU0iLG1lcmdlX3ZlbG8pCmYoIkNOTjEiLGRzMSkKCmBgYAoKCmBgYHtyfQpzYXZlUkRTKG1lcmdlX3ZlbG8sImRhdGFzZXQxX3ZlbG8uUkRTIikKYGBgCgoKYGBge3J9Cm1lcmdlX3ZlbG8gPC0gUnVuVmVsb2NpdHkob2JqZWN0ID0gbWVyZ2VfdmVsbywgZGVsdGFUID0gMSwga0NlbGxzID0gMjUsIGZpdC5xdWFudGlsZSA9IDAuMDIsIG5jb3JlcyA9IDMpICMgZml0dGluZyBnYW1tYSBjb2VmZmljaWVudHMg55So5pe26ZW/CmBgYAoKCmBgYHtyfQptZXJnZV92ZWxvIDwtIHJlYWRSRFMoImRhdGFzZXQyX0FDX3ZlbG8uUkRTIikKCgppZGVudC5jb2xvcnMgPC0gY29sb3JzX2xpc3RbMTpsZW5ndGgoeCA9IGxldmVscyh4ID0gbWVyZ2VfdmVsbykpXQpuYW1lcyh4ID0gaWRlbnQuY29sb3JzKSA8LSBsZXZlbHMoeCA9IG1lcmdlX3ZlbG8pCmNlbGwuY29sb3JzIDwtIGlkZW50LmNvbG9yc1tJZGVudHMob2JqZWN0ID0gbWVyZ2VfdmVsbyldCgpuYW1lcyh4ID0gY2VsbC5jb2xvcnMpIDwtIGNvbG5hbWVzKHggPSBtZXJnZV92ZWxvKQpwbmcoImRhdGFzZXQxX3ZlbG9jaXR5LnBuZyIpCnNob3cudmVsb2NpdHkub24uZW1iZWRkaW5nLmNvcihlbWIgPSBFbWJlZGRpbmdzKG9iamVjdCA9IG1lcmdlX3ZlbG8sIHJlZHVjdGlvbiA9ICJ1bWFwIiksIHZlbCA9IFRvb2wob2JqZWN0ID0gbWVyZ2VfdmVsbywgc2xvdCA9ICJSdW5WZWxvY2l0eSIpLCBuID0gMjAwLCBzY2FsZSA9ICJzcXJ0IiwgY2VsbC5jb2xvcnMgPSBhYyh4ID0gY2VsbC5jb2xvcnMsIGFscGhhID0gMC41KSwgCiAgICBjZXggPSAwLjgsIGFycm93LnNjYWxlID0gMywgc2hvdy5ncmlkLmZsb3cgPSBUUlVFLCBtaW4uZ3JpZC5jZWxsLm1hc3MgPSAwLjUsIGdyaWQubiA9IDQwLCBhcnJvdy5sd2QgPSAxLCAKICAgIGRvLnBhciA9IEZBTFNFLCBjZWxsLmJvcmRlci5hbHBoYSA9IDAuMSkKZGV2Lm9mZigpCgojIHBsb3QgPC0gdFNORS52ZWxvY2l0eS5wbG90KHZlbCA9IFRvb2wob2JqZWN0ID0gc3AxX3ZlbG8sIHNsb3QgPSAiUnVuVmVsb2NpdHkiKSkKYGBgCgoKYGBge3J9CnNvdXJjZSgiLi4vdmFzY3VsYXItYW5hbHlzaXMvc2V1cmF0VG9Bbm5EYXRhQ29tYmluZWQuUiIpCmBgYAoKYGBge3J9Cmg1YWRfb3V0cHV0IDwtICJkYXRhc2V0MV9TTUNfdmVsby5oNWFkIiAgCgpsaWJyYXJ5KHJldGljdWxhdGUpCmxpYnJhcnkoTWF0cml4KQp3cml0ZU1NKHQobWVyZ2VfdmVsb0Bhc3NheXMkU0NUQGNvdW50cyksIGZpbGU9J2NvbWJpbmVkLm10eCcpCndyaXRlTU0odChtZXJnZV92ZWxvQGFzc2F5cyRzcGxpY2VkQGNvdW50cyksIGZpbGU9J3NwbGljZWQubXR4JykKd3JpdGVNTSh0KG1lcmdlX3ZlbG9AYXNzYXlzJHVuc3BsaWNlZEBjb3VudHMpLCBmaWxlPSd1bnNwbGljZWQubXR4JykKd3JpdGUuY3N2KHJvd25hbWVzKG1lcmdlX3ZlbG9AYXNzYXlzJHNwbGljZWRAY291bnRzKSwgZmlsZSA9ICJnZW5lcy5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkKd3JpdGUuY3N2KG1lcmdlX3ZlbG9AcmVkdWN0aW9ucyR1bWFwQGNlbGwuZW1iZWRkaW5ncywgZmlsZSA9ICJ1bWFwLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQp3cml0ZS5jc3YobWVyZ2VfdmVsb0ByZWR1Y3Rpb25zJHBjYUBjZWxsLmVtYmVkZGluZ3MsIGZpbGUgPSAicGNhLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQp3cml0ZS5jc3YoY29sbmFtZXMobWVyZ2VfdmVsb0Bhc3NheXMkc3BsaWNlZEBjb3VudHMpLCBmaWxlID0gImNlbGxzLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQp3cml0ZS5jc3YobWVyZ2VfdmVsb0BtZXRhLmRhdGEsIGZpbGUgPSAibWV0YS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkKCnNvdXJjZV9weXRob24oJ34vc2NSTkFzZXEvdmFzY3VsYXItYW5hbHlzaXMvYnVpbGQucHknKQpidWlsZChoNWFkX291dHB1dCwgcGNhID0gVFJVRSwgdW1hcCA9IFRSVUUpCmZpbGUucmVtb3ZlKCdjb21iaW5lZC5tdHgnKQpmaWxlLnJlbW92ZSgnc3BsaWNlZC5tdHgnKQpmaWxlLnJlbW92ZSgndW5zcGxpY2VkLm10eCcpCmZpbGUucmVtb3ZlKCdnZW5lcy5jc3YnKQpmaWxlLnJlbW92ZSgnY2VsbHMuY3N2JykKZmlsZS5yZW1vdmUoJ3VtYXAuY3N2JykKCmZpbGUucmVtb3ZlKCdwY2EuY3N2JykKZmlsZS5yZW1vdmUoJ21ldGEuY3N2JykKCgpgYGAKCgojIOWPquWcqFNNQ+S6mue+pOS4rei/m+ihjApgYGB7cn0KU01DX3ZlbG8gPC0gc3Vic2V0KG1lcmdlX3ZlbG8sIGlkZW50cyA9ICJTTUMiKQpSdW5WZWxvY2l0eShvYmplY3QgPSBTTUNfdmVsbywgZGVsdGFUID0gMSwga0NlbGxzID0gMjUsIGZpdC5xdWFudGlsZSA9IDAuMDIpCmlkZW50LmNvbG9ycyA8LSBjb2xvcnNfbGlzdFsxOmxlbmd0aCh4ID0gbGV2ZWxzKHggPSBTTUNfdmVsbykpXQpuYW1lcyh4ID0gaWRlbnQuY29sb3JzKSA8LSBsZXZlbHMoeCA9IFNNQ192ZWxvKQpjZWxsLmNvbG9ycyA8LSBpZGVudC5jb2xvcnNbSWRlbnRzKG9iamVjdCA9IFNNQ192ZWxvKV0KCm5hbWVzKHggPSBjZWxsLmNvbG9ycykgPC0gY29sbmFtZXMoeCA9IFNNQ192ZWxvKQpwbmcoIlNNQ192ZWxvY2l0eS5wbmciKQpzaG93LnZlbG9jaXR5Lm9uLmVtYmVkZGluZy5jb3IoZW1iID0gRW1iZWRkaW5ncyhvYmplY3QgPSBTTUNfdmVsbywgcmVkdWN0aW9uID0gInVtYXAiKSwgdmVsID0gVG9vbChvYmplY3QgPSBTTUNfdmVsbywgc2xvdCA9ICJSdW5WZWxvY2l0eSIpLCBuID0gMjAwLCBzY2FsZSA9ICJzcXJ0IiwgY2VsbC5jb2xvcnMgPSBhYyh4ID0gY2VsbC5jb2xvcnMsIGFscGhhID0gMC41KSwgCiAgICBjZXggPSAwLjgsIGFycm93LnNjYWxlID0gMywgc2hvdy5ncmlkLmZsb3cgPSBUUlVFLCBtaW4uZ3JpZC5jZWxsLm1hc3MgPSAwLjUsIGdyaWQubiA9IDQwLCBhcnJvdy5sd2QgPSAxLCAKICAgIGRvLnBhciA9IEZBTFNFLCBjZWxsLmJvcmRlci5hbHBoYSA9IDAuMSkKZGV2Lm9mZigpCmBgYAoKCkFkZCBhIG5ldyBjaHVuayBieSBjbGlja2luZyB0aGUgKkluc2VydCBDaHVuayogYnV0dG9uIG9uIHRoZSB0b29sYmFyIG9yIGJ5IHByZXNzaW5nICpDdHJsK0FsdCtJKi4KCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ3RybCtTaGlmdCtLKiB0byBwcmV2aWV3IHRoZSBIVE1MIGZpbGUpLgoKVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLgo=